using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using MyCollections.Model;

namespace MyCollections.Utils
{
    class Xml
    {
        public static XmlNodeList GetXmlNodeList(string file, string xpath)
        {
            XmlDocument xmldoc = getXML(file);
            
            return GetXmlNodeList(xmldoc, xpath);
        }

        public static XmlNodeList GetXmlNodeList(XmlDocument xmldoc, string xpath)
        {
            XmlNamespaceManager xmlns = new XmlNamespaceManager(xmldoc.NameTable);
            XmlNodeList xmlnodelist = xmldoc.SelectNodes(xpath, xmlns);

            return xmlnodelist;
        }

        public static XmlDocument getXML(string filepath)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(filepath);
            return doc;
        }

        /// <summary>
        /// Serializes an object into an Xml Document
        /// </summary>
        /// <param name="o">The object to serialize</param>
        /// <returns>An Xml Document consisting of said object's data</re
        public static XmlDocument Serialize(object o)
        {
            XmlSerializer s = new XmlSerializer(o.GetType());

            //MemoryStream ms = new MemoryStream();
            Stream xmlFile = new FileStream(@"c:\list.xml", FileMode.Append, FileAccess.Write);
            StreamWriter writer = new StreamWriter(xmlFile, new UTF8Encoding());
            /*writer.Formatting = Formatting.Indented;
            writer.IndentCha = ' ';
            writer.Indentation = 5;*/
            Exception caught = null;

            try
            {
                s.Serialize(writer, o);
                XmlDocument xml = new XmlDocument();
                string xmlString = xmlFile.ToString();
                xml.LoadXml(xmlString);
                return xml;
            }
            catch (Exception e)
            {
                caught = e;
            }
            finally
            {
                writer.Close();
                xmlFile.Close();

                if (caught != null)
                    throw caught;
            }
            return null;
        }

        /// <summary>
        /// Deserializes an xml document back into an object
        /// </summary>
        /// <param name="xml">The xml data to deserialize</param>
        /// <param name="type">The type of the object being deserialized</param>
        /// <returns>A deserialized object</returns>
        public static object Deserialize(XmlDocument xml, Type type)
        {
            XmlSerializer s = new XmlSerializer(type);
            string xmlString = xml.OuterXml.ToString();
            byte[] buffer = ASCIIEncoding.UTF8.GetBytes(xmlString);
            MemoryStream ms = new MemoryStream(buffer);
            XmlReader reader = new XmlTextReader(ms);
            Exception caught = null;

            try
            {
                object o = s.Deserialize(reader);
                return o;
            }

            catch (Exception e)
            {
                caught = e;
            }
            finally
            {
                reader.Close();

                if (caught != null)
                    throw caught;
            }
            return null;
        }
    }
}
